package com.itcast.googleplay.ui;

import java.util.ArrayList;
import java.util.List;

import com.itcast.googleplay.utils.UIUtils;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class FlowLayout2 extends ViewGroup {
	//控件的水平间距
	private int horizontalSpacing = UIUtils.dip2px(10);
	//行和行间的竖直间距
	private int verticalSpacing = UIUtils.dip2px(15);
	
	//此集合用于存储行对象
	private List<Line> lineList = new ArrayList<Line>();
	private Line line;
	
	public FlowLayout2(Context context) {
		this(context,null);
	}

	public FlowLayout2(Context context, AttributeSet attrs) {
		this(context, attrs,-1);
	}

	public FlowLayout2(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	
	//widthMeasureSpec	32位数（（2）模式+（30）具体大小）		32位2机制数
	//heightMeasureSpec
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		//1.获取当前自定义控件的宽度大小(此宽度是屏幕的宽度)
		int width = MeasureSpec.getSize(widthMeasureSpec);
		//2.获取每一行的可用宽度大小
		int usedWidth = width - getPaddingLeft() - getPaddingRight();
		//3.创建一个行对象,行对象在后续操作中,需要去添加控件
		line = new Line();
		//4.行对象,最终是要添加到行的集合中的
		lineList.clear();
		//5.获取flowLayout中的每一个控件(TextView),判断在那一行去添加
		for (int i = 0; i < getChildCount(); i++) {
			//6.获取每一个TextView控件,然后判断添加在那一行
			View childView = getChildAt(i);
			//7.测量一下
			childView.measure(0, 0);
			//8.循环遍历到的控件的宽度
			int childWidth = childView.getMeasuredWidth();
			int childHeight = childView.getMeasuredHeight();
			//9.参照行对象中放置控件处理逻辑图片编写代码
			if(line.getLineViewCount() == 0){
				//此行没有控件,则将view添加在行对象中
				line.addLineView(childView);
				
			}else if(childWidth+line.lineWidth+horizontalSpacing>usedWidth){
				//childWidth+此行已经使用的宽度+horizontalSpacing>usedWidth
				//将上一行的行对象line,添加到集合中
				lineList.add(line);
				
				//换行(换一个新的Line对象)
				line = new Line();
				//在新行上放上上一行放不下的控件
				line.addLineView(childView);
			}else{
				line.addLineView(childView);
			}
			
			//将最后一行加入集合,当处理最后一个view的时候,肯定是在最后一个行对象上去添加,所以将此行对象加入集合
			if(i == getChildCount()-1){
				lineList.add(line);
			}
		}
		
		//10.计算当前FlowLayout控件的高度
		//底部内间距和顶部内间距叠加
		int height = getPaddingBottom()+getPaddingTop();
		//叠加行的高度
		for (int i = 0; i < lineList.size(); i++) {
			Line line = lineList.get(i);
			height += line.lineHeight;
		}
		//叠加行间距
		height += verticalSpacing*(lineList.size()-1);
		
		//指定控件宽高的32位数据
		widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
		heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
		
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		//行对象放置
		int left = getPaddingLeft();
		int top = getPaddingTop();
		for (int i = 0; i < lineList.size(); i++) {
			Line line  = lineList.get(i);
			line.lineViewLayout(left, top);
			
			top = top + line.lineHeight+verticalSpacing;
		}
	}
	
	//行对象
	public class Line{
		//行对象的高度
		public int lineHeight;
		//行对象的使用宽度
		public int lineWidth;
		//行对象中添加view所在的集合
		public List<View> viewList = new ArrayList<View>();
		
		//提供一个添加控件的方法
		public void addLineView(View view){
			//1,获取控件高度,添加进来控件的最高的高度,就是行的高度
			view.measure(0, 0);
			int viewHeight = view.getMeasuredHeight();
			//第一个控件加进来的时候   lineHeight = 0  控件的高度假设100  单前行高度取100
			//第二个控件加进来的时候   lineHeight = 100   第二个控件高度是200		单前行高度取100
			lineHeight = Math.max(lineHeight, viewHeight);
			//2,获取控件的宽度
			int viewWidth = view.getMeasuredWidth();
			//3,计算当前行已经使用的宽度总大小
			//一个控件:viewWidth+水平间距		行宽度1  = 0+宽度1+间距
			//二个控件:viewWidth+水平间距+第二个控件viewWidth+水平间距   行宽度2  = 行宽度1+宽度2+间距
			//三个控件:viewWidth+水平间距+第二个控件viewWidth+水平间距+第三个控件viewWidth+水平间距   行宽度3  = 行宽度2+宽度3+间距
			lineWidth += viewWidth+horizontalSpacing;
			//4,记录在行中添加的view的个数
			viewList.add(view);
		}
		
		//此行有多少个控件方法
		public int getLineViewCount(){
			return viewList.size();
		}
		
		//行中控件放置的方法
		//定义完了left和top,就是定了左上角距离左侧和距离顶端间距,此间距固定,则能确认控件的摆放位置
		//此位置是给行中第一个控件安放左上角坐标
		public void lineViewLayout(int left,int top){
			//获取当前行右侧的留白区域
			int usedWidth = getMeasuredWidth()-getPaddingLeft() -getPaddingRight();
			//计算留白区域的总大小
			int totalSurplusWidth = usedWidth - lineWidth;
			//将留白区域分配给当前行的每一个控件
			int surplusWidth = totalSurplusWidth/viewList.size();
			
			//1.处理当前行中,所有的view的位置的安放
			for (int i = 0; i < viewList.size(); i++) {
				//2.循环遍历行中的每一个控件,后续需要给其指定位置
				View view = viewList.get(i);					//view1
				//3.获取循环遍历控件的宽度和高度
				view.measure(0, 0);
				int viewWidth = view.getMeasuredWidth();		//view宽度
				int viewHeight = view.getMeasuredHeight();
				//4.循环遍历到的每一个控件,需要添加剩余空间平均分配的宽度大小
				viewWidth = viewWidth+surplusWidth;				//view真实宽度 = view宽度+补充
				
				//5.重新定义view的宽高大小
				int width32 = MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY);
				int height32 = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY);
				
				//6.让view按照上诉的宽高32位数改变控件的宽高
				view.measure(width32, height32);
				
				
				//7.指定循环过程中每一个控件的位置
				
				//第一次循环		left   top	right = left+view真实宽度    bottom = top+view高度
				
				//第二次循环		left = 第一次循环得到的left+第二个控件的宽度+间距
				//第二次循环		left = left+view1真实宽度+水平间距+第二个控件宽度+间距
				view.layout(left,top, left+viewWidth, top+viewHeight);
				
				//第一次循环得到的left = left+view1真实宽度+水平间距
				left = left + viewWidth+horizontalSpacing;
			}
		}
	}

}
